home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Game-Power
/
Amiga Game-Power.iso
/
pd mix ii
/
sprite ed
/
popcolors
/
popcolours.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-20
|
16KB
|
639 lines
/*:ts=8 */
/* >> PopColours: The amazing colour-set control panel <<
** >> From The Transactor - THE Magazine for Commodore Computing <<
**
** November 1986, Version 1.0
**
** - uses proportional gadgets for setting R G B
** and allows alteration of any colour register
** - operates on the TOPMOST OR SECOND SCREEN, so
** lets you change the colours of any currently
** executing program with its own screen
** - only opens up when selected, so it doesn't eat up
** screen space when you're not using it
**
** >> THIS PROGRAM MAY BE FREELY DISTRIBUTED <<
**
** (c) 1986, AHA! (Acme Heuristic Applications!)
**
** Written by Chris Zamara and Nick Sullivan
*/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <graphics/view.h>
/* defines for defaults, positioning, sizes, etc. */
#define SCREEN2INIT FALSE /* default to topmost screen */
#define GADGHEIGHT 10L /* height of proportional RGB gadgets */
#define RTOP 15L /* y position of top of Red gadget */
#define GTOP 28L /* " " " Green gadget */
#define BTOP 41L /* " " " Blue gadget */
#define CVAL 177L /* x position of colour values */
#define CPOSX 195L /* x position of colour register indicator */
#define CPOSY 63L /* y position of " " ... */
#define RPOSX 115L /* x position of Register text */
#define SCRPOSX 15L /* x position of screen indicator */
#define SCRPOSY 63L /* y position of screen indicator */
#define UPGADGX 197L /* x position of up gadget */
#define UPGADGY 10L /* y position of up gadget */
#define DNGADGX 197L /* x position of down gadget */
#define DNGADGY 32L /* y position of down gadget */
#define COLORGADGET 1 /* ID for RGB gadgets */
#define UPGADGET 2 /* ID for up gadget */
#define DOWNGADGET 3 /* ID for down gadget */
#define SCREENGADGET 4 /* ID for down gadget */
#define ARROWDELAY 5 /* # of ticks before repeating up/down */
#define DELAY 100000 /* pause for "no 2nd scrn" message */
#define POTINC 0x1111 /* amount added to each colour pot per click */
#define RTEXT (RTOP+(GADGHEIGHT >> 1)+2) /* gadget text position */
#define GTEXT (GTOP+(GADGHEIGHT >> 1)+2)
#define BTEXT (BTOP+(GADGHEIGHT >> 1)+2)
/* global structure declarations */
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct ViewPort *vp;
struct RastPort *rp;
struct IntuiMessage *GetMsg(), *message;
struct Window *OpenWindow(), *gwind, *SmallWind;
struct Screen *TheScreen;
/* function declarations */
APTR OpenLibrary();
USHORT GetRGB4();
USHORT GadgPressed();
BOOL BigWindow();
/* gadget structures for colour controls */
struct Gadget gadgR, gadgG, gadgB;
/* gadget structures for up/down arrows and screen selector */
struct Gadget gadgUp, gadgDown, gadgScreen;
/* define NewWindow structure for our window */
struct NewWindow GadgWind = {
400, 16, 233, 72, /* left, top, width, height */
-1, -1, /* use screen colours */
GADGETDOWN /* IDCMP flags */
| GADGETUP
| MOUSEBUTTONS
| INTUITICKS
| INACTIVEWINDOW
| CLOSEWINDOW,
WINDOWDEPTH /* window flags */
| WINDOWCLOSE
| WINDOWDRAG
| INACTIVEWINDOW
| RMBTRAP
| ACTIVATE
| SMART_REFRESH,
&gadgUp, /* first gadget in list */
NULL,
(UBYTE *)"PopColours 1.0", /* window title */
NULL, /* ptr to screen */
NULL,
0, 0, 0, 0, /* sizing limits (non-resizable)*/
WBENCHSCREEN
};
/* also make NewWindow structure for small window */
struct NewWindow SWind;
/* PropInfo structures for control gadgets */
struct PropInfo propinfR, propinfG, propinfB;
/* control knob Image structures */
struct Image knobR, knobG, knobB;
/* co-ordinate of points of up/down arrows */
SHORT UpXY[8] = { 13,0, 25,17, 0,17, 13,0 };
SHORT DownXY[8] = { 0,0, 25, 0, 13,17, 0,0 };
/* Border structure for Up-Arrow gadget */
struct Border UpArrow = {
3, 2,
1, 0, JAM1,
4,
UpXY,
NULL
};
/* Border structure for Down-Arrow gadget */
struct Border DownArrow = {
3, 2,
1, 0, JAM1,
4,
DownXY,
NULL
};
/* this next array is for fast'n'easy integer to ASCII conversion */
char *cnum[32] = { "00", "01", "02", "03", "04", "05", "06", "07",
"08", "09", "10", "11", "12", "13", "14", "15",
"16", "17", "18", "19", "20", "21", "22", "23",
"24", "25", "26", "27", "28", "29", "30", "31",
};
USHORT colreg = 0; /* current colour register */
BOOL Screen2Flag; /* false=top screen, true=second screen */
BOOL Old2Flag; /* previous value of Screen2Flag */
main (argc, argv)
int argc;
char *argv[];
{
/* open intuition and graphics libraries */
if ( (IntuitionBase = (struct IntuitionBase *)
OpenLibrary ("intuition.library", 0L) ) == NULL)
exit (0L);
if ( (GfxBase = (struct GfxBase *)
OpenLibrary ("graphics.library", 0L) ) == NULL) {
CloseLibrary (IntuitionBase);
exit (0L);
}
/* second arg specifies start-up colour register */
if (argc == 2)
colreg = atoi(argv[1]);
/* switch between small and big windows until big is closed */
do {
SmallWindow();
} while (BigWindow());
/* close everything up before ending */
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
}
BOOL BigWindow ()
{
ULONG msgclass; /* message class from IDCMP */
USHORT msgcode; /* message code from IDCMP */
APTR IAddr; /* pointer to gadget from IDCMP */
USHORT WhichGadg; /* ID of selected gadget */
USHORT TickStart; /* countdown for up/down arrow repeat delay */
BOOL GadgSel = FALSE; /* set when a colour gadget is selected */
BOOL RegSel = FALSE; /* set when up or down gadget is selected */
BOOL window_still_open = TRUE;
BOOL window_active = TRUE;
GadgSetup(); /* initialize gadget structures */
Screen2Flag = SCREEN2INIT;
Old2Flag = !SCREEN2INIT;
/* now attempt to open the window containing the gadgets */
if ((gwind = OpenWindow(&GadgWind)) == NULL) {
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
exit(0L);
}
/* get ptr to rastport for graphics routines */
rp = gwind->RPort;
/* set RGB gadget positions to current colours */
SetColrs();
/* put up labels on window display */
WinText();
/* put up colour register number indicator */
RegIndicate();
/*** main event loop ***/
while (window_still_open && window_active) {
/* wait politely, except when sliding a colour gadget */
if (! GadgSel)
Wait (1L << gwind->UserPort->mp_SigBit);
while (message = GetMsg(gwind->UserPort)) {
/* get what we need from the message port */
msgclass = message->Class;
msgcode = message->Code;
IAddr = message->IAddress;
ReplyMsg(message); /* reply to message right away */
/* now we can interpret the message */
/* check for gadget selected */
if (msgclass == GADGETDOWN)
WhichGadg = GadgPressed(IAddr, &GadgSel,
&RegSel, &TickStart);
/* check if gadget released, even if off of gadget */
else if ( (msgclass == MOUSEBUTTONS
&& msgcode == SELECTUP)
|| msgclass == GADGETUP )
GadgReleased(IAddr, &GadgSel, &RegSel,
WhichGadg);
/* auto-repeat arrow gadgets after delay */
else if (msgclass == INTUITICKS && RegSel) {
/* wait ARROWDELAY ticks before repeating */
if (TickStart++ > ARROWDELAY)
UpdateColReg(WhichGadg);
}
/* finish up if the close gadget is clicked */
else if (msgclass == CLOSEWINDOW)
window_still_open = FALSE;
/* exit if window made inactive */
else if (msgclass == INACTIVEWINDOW)
window_active = FALSE;
}
if (GadgSel)
/* set colour to pot values */
ReadGadg();
}
/* update NewWindow struct in case window has been moved */
GadgWind.LeftEdge = gwind->LeftEdge;
GadgWind.TopEdge = gwind->TopEdge;
CloseWindow(gwind);
return(window_still_open);
}
SmallWindow ()
{
ULONG msgclass; /* message class from IDCMP */
BOOL activated = FALSE;
SWind = GadgWind; /* almost like big window, */
/* except for ... */
SWind.Height = 11;
SWind.IDCMPFlags = ACTIVEWINDOW;
SWind.FirstGadget = NULL;
SWind.Flags = WINDOWDEPTH | ACTIVEWINDOW;
/* attempt to open the small window */
if ((SmallWind = OpenWindow(&SWind)) == NULL) {
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
exit(0L);
}
Wait (1L << SmallWind->UserPort->mp_SigBit);
while (message = GetMsg(SmallWind->UserPort)) {
msgclass = message->Class;
ReplyMsg(message); /* reply to message right away */
if (msgclass == ACTIVEWINDOW)
activated = TRUE;
}
/* update NewWindow struct in case window has been moved */
GadgWind.LeftEdge = SmallWind->LeftEdge;
GadgWind.TopEdge = SmallWind->TopEdge;
CloseWindow(SmallWind);
}
USHORT GadgPressed (IAddr, GadgSel, RegSel, TickStart)
/* set flags and call appropriate routines when a gadget is clicked */
struct Gadget *IAddr;
BOOL *GadgSel, *RegSel;
USHORT *TickStart;
{
USHORT WhichGadg;
/* get gadget type */
WhichGadg = IAddr->GadgetID;
/* rgb gadget? */
if (WhichGadg == COLORGADGET) {
*GadgSel = TRUE;
/* update settings if 2nd screen gone */
if (Screen2Flag
&& IntuitionBase->FirstScreen->NextScreen == NULL)
UpdateColReg(0);
}
/* up/down gadget? */
else if (WhichGadg == UPGADGET || WhichGadg == DOWNGADGET) {
*RegSel = TRUE;
*TickStart = 0; /* start delay timer */
UpdateColReg(WhichGadg);
}
/* Screen select gadget? */
else if (WhichGadg == SCREENGADGET) {
Screen2Flag = !Screen2Flag;
UpdateColReg(0);
}
return (WhichGadg);
}
GadgReleased (IAddr, GadgSel, RegSel, WhichGadg)
/* a gadget has been released - set flags and call appropriate routines */
struct Gadget *IAddr;
BOOL *GadgSel, *RegSel;
USHORT WhichGadg;
{
if (WhichGadg == COLORGADGET) {
ReadGadg();
if ( ( ((struct PropInfo *)(IAddr->SpecialInfo))->Flags )
& KNOBHIT )
SetColrs(); /* re-position knob if it was moved */
*GadgSel = FALSE; /* colour gadget no longer selected */
}
else
*RegSel = FALSE; /* ..or other gadget no longer selected */
}
ReadGadg ()
/* read gadget pot values and set colour register 'colreg' accordingly */
{
USHORT RedVal, GrnVal, BluVal;
RedVal = propinfR.HorizPot / POTINC;
GrnVal = propinfG.HorizPot / POTINC;
BluVal = propinfB.HorizPot / POTINC;
/* get viewport of topmost or second screen */
vp = &(TheScreen->ViewPort);
/* change colour register */
SetRGB4(vp, (ULONG)colreg, (ULONG)RedVal,
(ULONG)GrnVal, (ULONG)BluVal
);
PrintValues(RedVal, GrnVal, BluVal); /* numbers to right */
}
PrintValues (R, G, B)
/* print colour values to right of gadgets */
USHORT R, G, B;
{
SetAPen(rp, 1L);
Move(rp, CVAL, RTEXT);
Text(rp, cnum[R], 2L);
Move(rp, CVAL, GTEXT);
Text(rp, cnum[G], 2L);
Move(rp, CVAL, BTEXT);
Text(rp, cnum[B], 2L);
}
SetColrs ()
/* set gadget pot values according to rgb in register 'colreg' */
{
USHORT C0, R, G, B;
ULONG hpR, hpG, hpB;
/* get viewport of topmost screen */
ScreenPick(); /* select screen one or two */
vp = &(TheScreen->ViewPort);
/* get rgb of specified colour register */
C0 = GetRGB4(vp->ColorMap, (ULONG)(colreg) );
/* convert rgb to HorizPot values */
R = (C0 >> 8) & 0xF;
G = (C0 >> 4) & 0xF;
B = C0 & 0xF;
hpR = R * POTINC;
hpG = G * POTINC;
hpB = B * POTINC;
/* change gadgets to reflect new colours */
ModifyProp(&gadgR, gwind, NULL,
(ULONG)propinfR.Flags, hpR, 0L,
(ULONG)propinfR.HorizBody, 0L
);
ModifyProp(&gadgG, gwind, NULL,
(ULONG)propinfG.Flags, hpG, 0L,
(ULONG)propinfG.HorizBody, 0L
);
ModifyProp(&gadgB, gwind, NULL,
(ULONG)propinfB.Flags, hpB, 0L,
(ULONG)propinfB.HorizBody, 0L
);
PrintValues(R, G, B); /* colour numbers */
}
RegIndicate ()
/* show colour register number */
{
ULONG c;
/* first print register number */
Move(rp, CPOSX, CPOSY);
SetAPen(rp, 1L);
Text(rp, cnum[colreg], 2L);
/* now display a block in 'colreg' colour if changing this screen */
/* or background colour if changing another screen */
c = (IntuitionBase->ActiveScreen == TheScreen) ? colreg : 0;
Move(rp, CPOSX+24, CPOSY); /* move past text */
SetDrMd(rp, INVERSVID); /* inverse mode */
SetAPen(rp, c); /* set colour */
Text(rp, " ", 1L); /* print a space */
SetDrMd(rp, JAM2); /* set mode back to normal */
SetAPen(rp, 1L);
}
WinText ()
/* put up various labels on window */
{
SetAPen(rp, 1L);
Move(rp, 5L, RTEXT);
Text(rp, "R", 1L);
Move(rp, 5L, GTEXT);
Text(rp, "G", 1L);
Move(rp, 5L, BTEXT);
Text(rp, "B", 1L);
Move(rp, RPOSX, CPOSY);
Text(rp, " Register", 9L);
}
UpdateColReg (WhichGadg)
/* increment or decrement colour register */
/* if WhichGadg is 0, just display current settings */
USHORT WhichGadg;
{
USHORT numregs;
/* get number of bitplanes of screen */
ScreenPick(); /* set 'TheScreen' */
numregs = 1 << ((TheScreen->ViewPort).RasInfo->BitMap->Depth);
/* (whew!) */
/* increment or decrement colour register */
if (WhichGadg == UPGADGET)
colreg++;
else if (WhichGadg == DOWNGADGET)
colreg--;
colreg = colreg % numregs;
RegIndicate();
SetColrs();
}
ScreenPick ()
/* select top screen if Screen2Flag false **
** or second screen if true **
** and update display if necesary **
*/
{
ULONG d;
TheScreen = IntuitionBase->FirstScreen;
Move(rp, SCRPOSX, SCRPOSY);
SetAPen(rp, 1L);
SetBPen(rp, 3L); /* print in different background colour */
if (Screen2Flag) {
if (TheScreen->NextScreen == NULL) {
/* no second screen, put up temp. message */
Screen2Flag = FALSE;
Text(rp, "(no 2nd scrn)", 13L);
/* delay the easy way (ok, so we hog a second) */
for(d=0; d<DELAY; d++)
;
Move(rp, SCRPOSX, SCRPOSY);
Text(rp, " TOP SCREEN ", 13L);
}
else {
/* set pointer to second screen */
TheScreen = TheScreen->NextScreen;
if (Old2Flag != Screen2Flag)
Text(rp, "SECOND SCREEN", 13L);
}
}
if (!Screen2Flag && Old2Flag)
Text(rp, " TOP SCREEN ", 13L);
SetBPen(rp, 0L);
Old2Flag = Screen2Flag;
}
GadgSetup ()
{
/* proportional gadget for red */
gadgR.NextGadget = NULL;
gadgR.LeftEdge = 16;
gadgR.TopEdge = RTOP;
gadgR.Width = 155;
gadgR.Height = GADGHEIGHT;
gadgR.Flags = GADGHNONE | GADGIMAGE;
gadgR.Activation = GADGIMMEDIATE | RELVERIFY;
gadgR.GadgetType = PROPGADGET;
gadgR.GadgetRender = (APTR)&knobR;
gadgR.SelectRender = NULL;
gadgR.GadgetText = NULL;
gadgR.MutualExclude = NULL;
gadgR.SpecialInfo = (APTR)&propinfR;
gadgR.GadgetID = COLORGADGET;
gadgR.UserData = NULL;
/* up-arrow for changing colour register */
gadgUp.NextGadget = NULL;
gadgUp.LeftEdge = UPGADGX;
gadgUp.TopEdge = UPGADGY;
gadgUp.Width = 31;
gadgUp.Height = 21;
gadgUp.Flags = GADGHCOMP;
gadgUp.Activation = GADGIMMEDIATE | RELVERIFY;
gadgUp.GadgetType = BOOLGADGET;
gadgUp.GadgetRender = (APTR)↑
gadgUp.SelectRender = NULL;
gadgUp.GadgetText = NULL;
gadgUp.MutualExclude = NULL;
gadgUp.SpecialInfo = NULL;
gadgUp.GadgetID = UPGADGET;
gadgUp.UserData = NULL;
/* top/second screen indicator/selector */
gadgScreen = gadgUp;
gadgScreen.LeftEdge = SCRPOSX;
gadgScreen.TopEdge = SCRPOSY-5;
gadgScreen.Width = 104;
gadgScreen.Height = 11;
gadgScreen.Activation = GADGIMMEDIATE;
gadgScreen.GadgetRender = NULL;
gadgScreen.GadgetID = SCREENGADGET;
/* values needed for propinfo structure */
propinfR.Flags = FREEHORIZ | AUTOKNOB;
propinfR.HorizBody = 1 << 12; /* body increment (1/16) */
/* propinf structures for R G B gadgets all alike */
propinfG = propinfR;
propinfB = propinfR;
/* G and B gadgets same as R */
gadgG = gadgR;
gadgB = gadgR;
/* except for... */
gadgG.TopEdge = GTOP;
gadgB.TopEdge = BTOP;
gadgG.GadgetRender = (APTR)&knobG;
gadgB.GadgetRender = (APTR)&knobB;
gadgG.SpecialInfo = (APTR)&propinfG;
gadgB.SpecialInfo = (APTR)&propinfB;
/* define down gadget in terms of up gadget */
gadgDown = gadgUp;
gadgDown.GadgetRender = (APTR)↓
gadgDown.LeftEdge = DNGADGX;
gadgDown.TopEdge = DNGADGY;
gadgDown.GadgetID = DOWNGADGET;
/* link all gadgets by pointers */
gadgUp.NextGadget = &gadgDown;
gadgDown.NextGadget = &gadgR;
gadgR.NextGadget = &gadgG;
gadgG.NextGadget = &gadgB;
gadgB.NextGadget = &gadgScreen;
}